package edu.mit.compilers.assembly.x64.basic;

public class X64Register {
    public final String name;
    public final long bytes;
    public final boolean temporary; // temporary, not saved across calls; (caller-save)
    public final String leader;

    public X64Register(String name, long bytes, boolean temporary, String leader) {
        this.name = name;
        this.bytes = bytes;
        this.temporary = temporary;
        this.leader = leader;
    }

    // 16 64-bits registers
    public static final X64Register RAX = new X64Register("rax", 8, true, "rax");
    public static final X64Register RBX = new X64Register("rbx", 8, false, "rbx");
    public static final X64Register RCX = new X64Register("rcx", 8, true, "rcx");
    public static final X64Register RDX = new X64Register("rdx", 8, true, "rdx");
    public static final X64Register RSI = new X64Register("rsi", 8, true, "rsi");
    public static final X64Register RDI = new X64Register("rdi", 8, true, "rdi");
    public static final X64Register RBP = new X64Register("rbp", 8, false, "rbp");
    public static final X64Register RSP = new X64Register("rsp", 8, true, "rsp");
    public static final X64Register R8  = new X64Register("r8",  8, true, "r8");
    public static final X64Register R9  = new X64Register("r9",  8, true, "r9");
    public static final X64Register R10 = new X64Register("r10", 8, true, "r10");
    public static final X64Register R11 = new X64Register("r11", 8, true, "r11");
    public static final X64Register R12 = new X64Register("r12", 8, false, "r12");
    public static final X64Register R13 = new X64Register("r13", 8, false, "r13");
    public static final X64Register R14 = new X64Register("r14", 8, false, "r14");
    public static final X64Register R15 = new X64Register("r15", 8, false, "r15");

    // program counter
    public static final X64Register RIP = new X64Register("rip", 8, false, "rip");


    public static X64Register getRegister(String register) {
        switch (register) {
            case "rax":     return RAX;
            case "rbx":     return RBX;
            case "rbp":     return RBP;
            case "rcx":     return RCX;
            case "rdx":     return RDX;
            case "rdi":     return RDI;
            case "rsi":     return RSI;
            case "rsp":     return RSP;
            case "r8" :     return R8;
            case "r9" :     return R9;
            case "r10":     return R10;
            case "r11":     return R11;
            case "r12":     return R12;
            case "r13":     return R13;
            case "r14":     return R14;
            case "r15":     return R15;
            default:
                assert false : "not support such register for user, which is " + register;
                return null;
        }
    }

    // TODO : 32-bits, 16-bits and 8-bits registers
    public static final X64Register AL      = new X64Register("al",   1, true, "rax");
    public static final X64Register BL      = new X64Register("bl",   1, false, "rbx");
    public static final X64Register CL      = new X64Register("cl",   1, true, "rcx");
    public static final X64Register DL      = new X64Register("dl",   1, true, "rdx");
    public static final X64Register SIL     = new X64Register("sil",  1, true, "rsi");
    public static final X64Register DIL     = new X64Register("dil",  1, true, "rdi");
    public static final X64Register BPL     = new X64Register("bpl",  1, false, "rbp");
    public static final X64Register SPL     = new X64Register("spl",  1, true, "rsp");
    public static final X64Register R8B     = new X64Register("r8b",  1, true, "r8");
    public static final X64Register R9B     = new X64Register("r9b",  1, true, "r9");
    public static final X64Register R10B    = new X64Register("r10b", 1, true, "r10");
    public static final X64Register R11B    = new X64Register("r11b", 1, true, "r11");
    public static final X64Register R12B    = new X64Register("r12b", 1, false, "r12");
    public static final X64Register R13B    = new X64Register("r13b", 1, false, "r13");
    public static final X64Register R14B    = new X64Register("r14b", 1, false, "r14");
    public static final X64Register R15B    = new X64Register("r15b", 1, false, "r15");
}
